<template>
  <tr class="input-item" :class="{require:config.require,error:!validate.ok&&userInputed}">
    <td class="input-title" :class="{notitle:!config.title}">
        <label :for="config.id">{{config.title}}</label>
    </td>
    <td class="input-body">
        <component :is="'input-'+config.type" :config="config" :value="value" @input="onInput"></component>
    </td>
  </tr>
</template>

<script>
/*import 'components/form/input/Select.js';
import 'components/form/input/EditableText.js';
import 'components/form/input/StaticText.js';
import 'components/form/input/Checkbox.js';
import 'components/form/input/Agree.js';*/
import inputText from './input/Text.vue';
import inputTextArea from './input/Textarea.vue';
import inputCover from './input/Cover.vue';
import inputEditor from './input/Editor.vue';
import inputRadio from './input/Radio.vue';
import inputDatePicker from './../controls/DatePicker.vue';
import inputSelectText from './input/SelectText.vue';

export default {
  name: 'inputItem',
  components:{
    "input-text":inputText,
    "input-textarea":inputTextArea,
    "input-cover":inputCover,
    "input-editor":inputEditor,
    "input-radio":inputRadio,
    "input-datepicker":inputDatePicker,
    "input-selecttext":inputSelectText
  },
  props: ['config', 'value'],
  data() {
    return {
      userInputed: false,
      validate: {
        ok: false,
        info: ''
      }
    };
  },
  methods: {
    onInput({value, twoWay}) {
      if (value !== this.value) {
        this.userInputed = true;
      }
      this.doValidate(value);
      this.$emit('input', {
        value,
        twoWay,
        name: this.config.name,
        validate: this.validate,
        byUser: this.userInputed
      });
      //}
    },
    getByteLen(val) {
      let len = 0;
      for (let i = 0; i < val.length; i++) {
        let a = val.charAt(i);
        if (a.match(/[^\x00-\xff]/ig) != null) {
          len += 2;
        }
        else {
          len += 1;
        }
      }
      return len;
    },
    /**
     * 根据 config验证一个表单值，返回一个object:
     * {
     *  ok : false, // 表示是否验证通过
     *  code : 0, // 验证错误编号
     *  info : '为必填项' // 默认的验证错误消息
     *  formattedInfo : '{title}为必填项' // 包含替换字符串的错误消息，{title}替换为需要的内容
     * }
     *
     * 具体的可选验证项由 config 的 extra.limit 定义，可选的limit如下
     * 1.表示长度限制的数组 [min,max[,char]],char=1时将做字与字符的区分，一个汉字为2个字符
     * 2.正则表达式
     * 3.一个验证用的function，返回格式需要和本方法相同
     * @param value
     * @returns {*}
     */
    doValidate(value) {
      let limit;
      if (this.config.extra && this.config.extra.limit) {
        limit = this.config.extra.limit;
      }
      if (Object.prototype.toString.apply(limit) === '[object Function]') {
        return this.validate = limit(value);
      }
      if (this.config.require && (value === '' || value === undefined || value === null )) {
        return this.validate = {ok: false, code: 0, info: '为必填项'};
      }
      if (this.config.require && value === false) {
        return this.validate = {ok: false, code: 0};
      }
      if (!!value && this.config.extra && (this.config.extra.limit || this.config.extra.letterRegExp)) {
        
        let regExp = this.config.extra.letterRegExp;
        
        if (this.config.extra.letterRegExp && !regExp.test(value)) {
          if (this.config.name == "name" || this.config.name == "description" || this.config.name == "aidSheet" || this.config.name == "otherContact") {
            return this.validate = {ok: false, code: 2, info: '只能使用中英文和数字'};
          }
          else {
            return this.validate = {ok: false, code: 2, info: '请输入正确的' + this.config.title};
          }
        }
        
        switch (Object.prototype.toString.apply(limit)) {
          case '[object Array]':
            let length = value.length;
            let unit = '个字';
            if (Array.isArray(value)) {
              unit = '项';
            }
            else if (limit.length === 3 && limit[2] === 1) {
              length = this.getByteLen(value);
              unit = '个字符';
            }
            if (length < limit[0]) {
              return this.validate = {ok: false, code: 1.1, info: `请输入${limit[0]}到${limit[1]}${unit}`};
            }
            if (length > limit[1]) {
              return this.validate = {ok: false, code: 1.2, info: `最多${limit[1]}${unit}`};
            }
            break;
          case '[object RegExp]':
            if (!limit.test(value)) {
              return this.validate = {ok: false, code: 2, info: '的格式不正确'};
            }
            break;
          default:
            return this.validate = {ok: true};
        }
      }
      return this.validate = {ok: true,};
    }
  },
  created() {
    let {value, name} = this.config;
    this.doValidate(value);
    this.$emit('input', {value, name, validate: this.validate, byUser: false});
  }
};
</script>

<style lang="less">
.input-item {
  &.require {
    .input-title label:before {
      content: "*";
      display: block;
      position: absolute;
      top: 0;
      right: 100%;
      color: #d33;
      text-align: center;
      line-height: 36px;
    }
  }
  .input-title {
    width: 2em;
    font-size: 20px;
    white-space: nowrap;
    &.notitle {
      label {
        display: none;
      }
    }
    label {
      display: block;
      position: relative;
      margin: 0 1em 0 .5em;
      color: #999;
      &:after {
        content: ":";
      }
    }
  }
}
</style>